local extension = Package("skjiangxing")
extension.extensionName = "jilvRem"

local U = require "packages/utility/utility"
local SkUtil = require "packages/jilvRem/utility/sk_util"

Fk:loadTranslationTable{
  ["skjiangxing"] = "极略三国-将星",
}

local sunluyu = General(extension, "sk__sunluyu", "wu", 3, 3, General.Female)
local sk__huilian = fk.CreateActiveSkill{
  name = "sk__huilian",
  anim_type = "support",
  prompt = "#sk__huilian",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local judge = {
      who = target,
      reason = self.name,
      pattern = ".",
      skipDrop = true,
    }
    room:judge(judge)
    if room:getCardArea(judge.card) == Card.Processing then
      if not target.dead then
        room:moveCardTo(judge.card, Card.PlayerHand, target, fk.ReasonJustMove, self.name, nil, true, target.id)
      else
        room:moveCardTo(judge.card, Card.DiscardPile, nil, fk.ReasonJustMove, self.name, nil, true)
      end
    end
    if judge.card.suit == Card.Heart and not target.dead and target:isWounded() then
      room:recover({
        who = target,
        num = 1,
        recoverBy = player,
        skillName = self.name,
      })
    end
  end,
}
local sk__wenliang = fk.CreateTriggerSkill{
  name = "sk__wenliang",
  anim_type = "drawcard",
  events = {fk.FinishJudge},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.card.color == Card.Red
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}
sunluyu:addSkill(sk__huilian)
sunluyu:addSkill(sk__wenliang)
Fk:loadTranslationTable{
  ["sk__sunluyu"] = "孙鲁育",
  ["#sk__sunluyu"] = "与虎谋皮",

  ["sk__huilian"] = "慧敛",
  [":sk__huilian"] = "出牌阶段限一次，你可以令一名角色判定，其获得生效后的判定牌，然后若结果为<font color='red'>♥</font>，其回复1点体力。",
  ["sk__wenliang"] = "温良",
  [":sk__wenliang"] = "当红色判定牌生效后，你可以摸一张牌。",
  ["#sk__huilian"] = "慧敛：令一名角色判定并获得判定牌，若为<font color='red'>♥</font>，其回复1点体力",

  ["$sk__huilian1"] = "别担心，此事还有转圜余地。",
  ["$sk__huilian2"] = "总有办法的。",
  ["$sk__wenliang"] = "到我怀里来~",
  ["~sk__sunluyu"] = "",
}

local chengyu = General(extension, "sk__chengyu", "wei", 3)
local sk__pengri = fk.CreateActiveSkill{
  name = "sk__pengri",
  anim_type = "drawcard",
  prompt = "#sk__pengri",
  card_num = 0,
  target_num = 0,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    player:drawCards(2, self.name)
    for _, p in ipairs(room:getOtherPlayers(player)) do
      if player.dead then return end
      if not p.dead and p:inMyAttackRange(player) then
        local use = room:askForUseCard(p, "slash", "slash", "#sk__pengri-slash:"..player.id, true, {must_targets = {player.id}})
        if use then
          use.extraUse = true
          room:useCard(use)
        end
      end
    end
  end,
}
local sk__danmou = fk.CreateTriggerSkill{
  name = "sk__danmou",
  anim_type = "masochism",
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.from and not data.from.dead and data.from ~= player and
      not (player:isKongcheng() and data.from:isKongcheng())
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {data.from.id})
    U.swapHandCards(room, player, player, data.from, self.name)
  end
}
chengyu:addSkill(sk__pengri)
chengyu:addSkill(sk__danmou)
Fk:loadTranslationTable{
  ["sk__chengyu"] = "程昱",
  ["#sk__chengyu"] = "筹妙绝伦",

  ["sk__pengri"] = "捧日",
  [":sk__pengri"] = "出牌阶段限一次，你可以摸两张牌，然后攻击范围内含有你的其他角色可以对你使用【杀】。",
  ["sk__danmou"] = "胆谋",
  [":sk__danmou"] = "当你受到伤害后，你可以与伤害来源交换手牌。",
  ["#sk__pengri"] = "捧日：你可以摸两张牌，然后其他角色可以对你使用【杀】",
  ["#sk__pengri-slash"] = "捧日：你可以对 %src 使用一张【杀】",

  ["$sk__pengri1"] = "捧泰山之日，裨吾主之明。",
  ["$sk__pengri2"] = "以将军之神武，霸王之业可图也！",
  ["$sk__danmou1"] = "背水为阵，伏兵十队！",
  ["$sk__danmou2"] = "兵只七百，尔可敢来攻？",
  ["~sk__chengyu"] = "",
}

local mizhu = General(extension, "sk__mizhu", "shu", 3)
local sk__ziguo = fk.CreateActiveSkill{
  name = "sk__ziguo",
  anim_type = "support",
  prompt = "#sk__ziguo",
  card_num = 0,
  target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter =function (self, to_select, selected, selected_cards, card, extra_data, player)
    return #selected == 0 and Fk:currentRoom():getPlayerById(to_select):isWounded()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:addPlayerMark(player, MarkEnum.MinusMaxCardsInTurn, 2)
    target:drawCards(2, self.name)
  end,
}
local sk__shangdao = fk.CreateTriggerSkill{
  name = "sk__shangdao",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Start and target:getHandcardNum() >= player:getHandcardNum()
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card = room:getNCards(1)
    room:moveCardTo(card, Card.Processing, nil, fk.ReasonJustMove, self.name, nil, true, player.id)
    room:delay(800)
    room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
  end,
}
mizhu:addSkill(sk__ziguo)
mizhu:addSkill(sk__shangdao)
Fk:loadTranslationTable{
  ["sk__mizhu"] = "糜竺",
  ["#sk__mizhu"] = "富甲一方",

  ["sk__ziguo"] = "资国",
  [":sk__ziguo"] = "出牌阶段限一次，你可以令一名已受伤的角色摸两张牌，若如此做，你于本回合手牌上限-2。",
  ["sk__shangdao"] = "商道",
  [":sk__shangdao"] = "锁定技，一名角色准备阶段，若其手牌数不小于你，你亮出牌堆顶牌并获得之。",
  ["#sk__ziguo"] = "资国：令一名已受伤角色摸两张牌，你本回合手牌上限-2",

  ["$sk__ziguo1"] = "国将不国，何以为家？",
  ["$sk__ziguo2"] = "举家之财力，资国之大计。",
  ["$sk__shangdao1"] = "别介意，在商言商。",
  ["$sk__shangdao2"] = "走过路过，不要错过。",
  ["~sk__mizhu"] = "",
}

local zhangren = General(extension, "sk__zhangren", "qun", 4)
local sk__fushe = fk.CreateTriggerSkill{
  name = "sk__fushe",
  mute = true,
  events = {fk.EventPhaseStart, fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    if target.phase == Player.Play then
      if event == fk.EventPhaseStart then
        return player:hasSkill(self) and not target.dead and player:inMyAttackRange(target)
      else
        if player:usedSkillTimes(self.name, Player.HistoryPhase) > 0 then
          local suit = U.ConvertSuit(player:getMark("@[private]sk__fushe-phase").value[1], "sym", "int")
          return #player.room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
            for _, move in ipairs(e.data) do
              if move.toArea == Card.DiscardPile then
                for _, info in ipairs(move.moveInfo) do
                  if Fk:getCardById(info.cardId).suit == suit then
                    return true
                  end
                end
              end
            end
          end, Player.HistoryPhase) > 0
        end
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local choices = table.map({"spade", "heart", "club", "diamond"}, function (s)
        return U.ConvertSuit(s, "str", "sym")
      end)
      table.insert(choices, "Cancel")
      local choice = player.room:askForChoice(player, choices, self.name, "#sk__fushe-invoke::"..target.id)
      if choice ~= "Cancel" then
        self.cost_data = choice
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    room:doIndicate(player.id, {target.id})
    if event == fk.EventPhaseStart then
      room:notifySkillInvoked(player, self.name, "control")
      U.setPrivateMark(player, "sk__fushe-phase", {self.cost_data})
    else
      room:notifySkillInvoked(player, self.name, "offensive")
      player:drawCards(1, self.name)
      if not target.dead then
        room:damage({
          from = player,
          to = target,
          damage = 1,
          skillName = self.name,
        })
      end
    end
  end,
}
zhangren:addSkill(sk__fushe)
Fk:loadTranslationTable{
  ["sk__zhangren"] = "张任",
  ["#sk__zhangren"] = "索命神射",

  ["sk__fushe"] = "伏射",
  [":sk__fushe"] = "你攻击范围内的角色出牌阶段开始时，你可以秘密选择一种花色；此阶段结束时，若此阶段中有此花色的牌进入弃牌堆，你摸一张牌并"..
  "对其造成1点伤害。",
  ["#sk__fushe-invoke"] = "伏射：秘密猜测本阶段是否将有此花色的牌进入弃牌堆，若猜对，你摸一张牌并对 %dest 造成1点伤害",
  ["@[private]sk__fushe-phase"] = "伏射",

  ["$sk__fushe1"] = "射掉那个骑白马的，重重有赏！",
  ["$sk__fushe2"] = "这一箭，就是要你死！",
  ["~sk__zhangren"] = "",
}

local zhangbao = General(extension, "sk__zhangbao", "qun", 3)
local sk__zhoufu = fk.CreateTriggerSkill{
  name = "sk__zhoufu",
  anim_type = "control",
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target ~= player and not player:isKongcheng() and not target.dead
  end,
  on_cost = function(self, event, target, player, data)
    local card = player.room:askForDiscard(player, 1, 1, false, self.name, true, ".", "#sk__zhoufu-invoke::"..target.id, true)
    if #card > 0 then
      self.cost_data = card
      player.room:doIndicate(player.id, {target.id})
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:throwCard(self.cost_data, self.name, player, player)
    if target.dead then return end
    local judge = {
      who = target,
      reason = self.name,
      pattern = ".|.|spade,club",
    }
    room:judge(judge)
    if target.dead then return end
    if judge.card.suit == Card.Spade then
      room:setPlayerMark(target, "@@sk__zhoufu-turn", 1)
    elseif judge.card.suit == Card.Club then
      room:askForDiscard(target, 2, 2, true, self.name, false)
    end
  end,
}
local sk__zhoufu_invalidity = fk.CreateInvaliditySkill {
  name = "#sk__zhoufu_invalidity",
  invalidity_func = function(self, from, skill)
    return from:getMark("@@sk__zhoufu-turn") > 0 and skill:isPlayerSkill(from)
  end
}
local sk__yingbing = fk.CreateTriggerSkill{
  name = "sk__yingbing",
  anim_type = "offensive",
  events = {fk.FinishJudge},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target ~= player and data.card.color == Card.Black and
      not player:isProhibited(target, Fk:cloneCard("thunder__slash")) and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#sk__yingbing-invoke::"..target.id)
  end,
  on_use = function(self, event, target, player, data)
    player.room:useVirtualCard("thunder__slash", nil, player, target, self.name, true)
  end,
}
sk__zhoufu:addRelatedSkill(sk__zhoufu_invalidity)
zhangbao:addSkill(sk__zhoufu)
zhangbao:addSkill(sk__yingbing)
Fk:loadTranslationTable{
  ["sk__zhangbao"] = "张宝",
  ["#sk__zhangbao"] = "地公将军",

  ["sk__zhoufu"] = "咒缚",
  [":sk__zhoufu"] = "其他角色回合开始时，你可以弃置一张手牌令其进行判定，若结果为：♠，其本回合所有技能无效；♣，其弃置两张牌。",
  ["sk__yingbing"] = "影兵",
  [":sk__yingbing"] = "每回合限一次，当一名角色的黑色判定牌生效后，你可以视为对其使用一张雷【杀】。",
  ["#sk__zhoufu-invoke"] = "咒缚：你可以弃置一张手牌令 %dest 判定，若为♠其本回合所有技能无效，若为♣其弃两张牌",
  ["@@sk__zhoufu-turn"] = "技能失效",
  ["#sk__yingbing-invoke"] = "影兵：是否视为对 %dest 使用一张雷【杀】？",

  ["$sk__zhoufu1"] = "孰死孰活，全听我令！",
  ["$sk__zhoufu2"] = "咒缚缠身，尔待何如？",
  ["$sk__yingbing1"] = "幻影成兵，助我退敌！",
  ["$sk__yingbing2"] = "四方神将，皆为我用！",
  ["~sk__zhangbao"] = "",
}

local bianfuren = General(extension, "sk__bianfuren", "wei", 3, 3, General.Female)
local sk__huage = fk.CreateActiveSkill{
  name = "sk__huage",
  anim_type = "control",
  card_num = 0,
  target_num = 0,
  prompt = "#sk__huage",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and
      table.find(Fk:currentRoom().alive_players, function (p)
        return not p:isNude()
      end)
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local targets = room:getAlivePlayers()
    room:doIndicate(player.id, table.map(targets, Util.IdMapper))
    for _, target in ipairs(targets) do
      if not target.dead and not target:isNude() then
        local cards = room:askForDiscard(target, 1, 999, true, self.name, false, ".", "#sk__huage-discard")
        local n = #table.filter(cards, function(id)
          return Fk:getCardById(id).trueName == "slash"
        end)
        if n > 0 and not target.dead then
          target:drawCards(n, self.name)
        end
      end
    end
  end,
}
local sk__muyi = fk.CreateTriggerSkill{
  name = "sk__muyi",
  anim_type = "control",
  events = {fk.EventPhaseStart, fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    if target ~= player and target.phase == Player.Play and not target.dead then
      if event == fk.EventPhaseStart then
        return player:hasSkill(self) and not target.dead and not target:isKongcheng()
      elseif event == fk.EventPhaseEnd then
        return player:usedSkillTimes(self.name, Player.HistoryPhase) > 0 and not player:isNude()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      return player.room:askForSkillInvoke(player, self.name, nil, "#sk__muyi-invoke::"..target.id)
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {target.id})
    if event == fk.EventPhaseStart then
      local n = math.min(#target:getCardIds("he"), 2)
      local cards = room:askForCard(target, n, n, false, self.name, false, ".", "#sk__muyi-give::"..player.id..":"..n)
      room:setPlayerMark(player, "sk__muyi-phase", n)
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonGive, self.name, nil, false, target.id)
    else
      local n = math.min(#player:getCardIds("he"), player:getMark("sk__muyi-phase"))
      local cards = room:askForCard(player, n, n, true, self.name, false, ".", "#sk__muyi-give::"..target.id..":"..n)
      room:moveCardTo(cards, Card.PlayerHand, target, fk.ReasonGive, self.name, nil, false, player.id)
    end
  end,
}
bianfuren:addSkill(sk__huage)
bianfuren:addSkill(sk__muyi)
Fk:loadTranslationTable{
  ["sk__bianfuren"] = "卞夫人",
  ["#sk__bianfuren"] = "奕世雍容",

  ["sk__huage"] = "化戈",
  [":sk__huage"] = "出牌阶段限一次，你可以令所有角色弃置至少一张牌，一名角色每以此法弃置一张【杀】，其摸一张牌。",
  ["sk__muyi"] = "母仪",
  [":sk__muyi"] = "其他角色出牌阶段开始时，你可以令其交给你两张手牌，若如此做，此阶段结束时，你交给其等量的牌。（不足则全交出）",
  ["#sk__huage"] = "化戈：令所有角色弃置至少一张牌",
  ["#sk__huage-discard"] = "化戈：请弃置至少一张牌，每弃一张【杀】摸一张牌",
  ["#sk__muyi-invoke"] = "母仪：是否令 %dest 交给你两张牌？",
  ["#sk__muyi-give"] = "母仪：请交给 %dest %arg张牌",

  ["$sk__huage1"] = "你们都歇停歇停吧。",
  ["$sk__huage2"] = "自家人，怎能自相残杀？",
  ["$sk__muyi1"] = "就交给我来打理吧。",
  ["$sk__muyi2"] = "择其中者足矣。",
  ["~sk__bianfuren"] = "",
}

local tianfeng = General(extension, "sk__tianfeng", "qun", 3)
local sk__sijian = fk.CreateTriggerSkill{
  name = "sk__sijian",
  anim_type = "control",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:isKongcheng() then
      local yes = false
      for _, move in ipairs(data) do
        if move.from == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand then
              yes = true
              break
            end
          end
        end
      end
      if yes then
        return player.hp > 0 and table.find(player.room:getOtherPlayers(player), function(p) return not p:isNude() end)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.map(table.filter(room:getOtherPlayers(player),
      function(p) return not p:isNude()
    end), Util.IdMapper)
    local to = room:askForChoosePlayers(player, targets, 1, 1, "#sk__sijian-choose:::"..player.hp, self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    local cards = room:askForCardsChosen(player, to, 1, player.hp, "he", self.name, "#sk__sijian-discard::"..to.id..":"..player.hp)
    room:throwCard(cards, self.name, to, player)
  end,
}
local sk__gangzhi = fk.CreateTriggerSkill{
  name = "sk__gangzhi",
  anim_type = "defensive",
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_cost = function(self, event, target, player, data)
    local prompt = "#sk__gangzhi1-invoke"
    if player:isKongcheng() then
      prompt = "#sk__gangzhi2-invoke"
    end
    return player.room:askForSkillInvoke(player, self.name, nil, prompt)
  end,
  on_use = function(self, event, target, player, data)
    if not player:isKongcheng() then
      player:throwAllCards("h")
      return true
    else
      player:turnOver()
      if not player.dead and player.maxHp > player:getHandcardNum() then
        player:drawCards(player.maxHp - player:getHandcardNum(), self.name)
      end
    end
  end,
}
tianfeng:addSkill(sk__sijian)
tianfeng:addSkill(sk__gangzhi)
Fk:loadTranslationTable{
  ["sk__tianfeng"] = "田丰",
  ["#sk__tianfeng"] = "",

  ["sk__sijian"] = "死谏",
  [":sk__sijian"] = "当你失去所有手牌后，你可以弃置一名其他角色至多X张牌（X为你的体力值）。",
  ["sk__gangzhi"] = "刚直",
  [":sk__gangzhi"] = "当你受到伤害时，若你：有手牌，你可以弃置所有手牌，然后防止此伤害；没有手牌，你可以翻面，然后将手牌摸至体力上限。",
  ["#sk__sijian-choose"] = "死谏：你可以弃置一名角色至多%arg张牌",
  ["#sk__sijian-discard"] = "死谏：弃置 %dest 至多%arg张牌",
  ["#sk__gangzhi1-invoke"] = "刚直：你可以弃置所有手牌，防止你受到的伤害",
  ["#sk__gangzhi2-invoke"] = "刚直：你可以翻面，将手牌摸至体力上限",

  ["$sk__sijian"] = "臣愿以死进言。",
  ["$sk__gangzhi1"] = "大丈夫当前斗死，不可苟活！",
  ["$sk__gangzhi2"] = "惜哉惜哉，臣有言而不得允。",
  ["~sk__tianfeng"] = "",
}

Fk:loadTranslationTable{
  ["sk_sp__huangyueying"] = "黄月英",
  ["#sk_sp__huangyueying"] = "开物成务",

  ["sk__muniu"] = "木牛",
  [":sk__muniu"] = "你的回合内，当牌移动至或移出一名角色的装备区后，你可以弃置一名角色一张手牌，或令一名角色摸一张牌。",
  ["sk__liuma"] = "流马",
  [":sk__liuma"] = "出牌阶段限一次，你可以弃置一张基本牌，然后令至多两名装备区内有牌的其他角色依次选择一项：1.将其装备区内的一张牌交给另一名"..
  "角色；2.令你获得其一张手牌。",
}

Fk:loadTranslationTable{
  ["sk_sp__machao"] = "马超",
  ["#sk_sp__machao"] = "西凉猛狮",

  ["sk__zhuiji"] = "追击",
  [":sk__zhuiji"] = "锁定技，当你对其他角色造成伤害后，你计算与其的距离-1。",
  ["sk__xionglie"] = "雄烈",
  [":sk__xionglie"] = "当你使用【杀】指定一个目标后，你可以选择一项：1.此【杀】不能被响应；2.此【杀】伤害+1。若你与所有其他角色的距离均为1，"..
  "则两项均执行。",
}

local sp_caiwenji = General(extension, "sk_sp__caiwenji", "wei", 3, 3, General.Female)
local sk__chenqing = fk.CreateTriggerSkill{
  name = "sk__chenqing",
  anim_type = "support",
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and
      #player.room:getOtherPlayers(target) > 0
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local to = room:askForChoosePlayers(player, table.map(room:getOtherPlayers(target), Util.IdMapper), 1, 1,
      "#sk__chenqing-choose::"..target.id..":"..(player:usedSkillTimes(self.name, Player.HistoryGame) + 1), self.name, true)
    if #to > 0 then
      self.cost_data = to[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data)
    to:drawCards(4, self.name)
    if to.dead or to:isNude() then return end
    local n = player:usedSkillTimes(self.name, Player.HistoryGame)
    local cards = room:askForDiscard(to, n, n, true, self.name, false, ".", "#sk__chenqing-discard::"..target.id..":"..n, true)
    local suits = {}
    for _, id in ipairs(cards) do
      if Fk:getCardById(id).suit ~= Card.NoSuit then
        table.insertIfNeed(suits, Fk:getCardById(id).suit)
      end
    end
    room:throwCard(cards, self.name, to, to)
    if #suits == #cards and not target.dead then
      room:useVirtualCard("peach", nil, to, target, self.name)
    end
  end,
}
local sk__mozhi = fk.CreateTriggerSkill{
  name = "sk__mozhi",
  anim_type = "control",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local room = player.room
      local name = ""
      local turn_event = room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
      if not turn_event then return end
      room.logic:getEventsByRule(GameEvent.UseCard, 1, function (e)
        local use = e.data[1]
        if use.from == target.id then
          name = use.card.name
          return true
        end
      end, turn_event.id)
      if name ~= "" then
        room:setPlayerMark(player, "sk__mozhi-turn", name)
        local card = Fk:cloneCard(name)
        return (card.type == Card.TypeBasic or card:isCommonTrick()) and player:canUse(card) and not player:prohibitUse(card)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local success, dat = player.room:askForUseActiveSkill(player, "sk__mozhi_viewas",
      "#sk__mozhi-invoke:::"..player:getMark("sk__mozhi-turn"), true)
    if success then
      self.cost_data = dat
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local card = Fk:cloneCard(player:getMark("sk__mozhi-turn"))
    card:addSubcards(self.cost_data.cards)
    card.skillName = "sk__mozhi"
    player.room:useCard{
      from = player.id,
      tos = table.map(self.cost_data.targets, function(id) return {id} end),
      card = card,
      extraUse = true,
    }
  end,
}
local sk__mozhi_viewas = fk.CreateViewAsSkill{
  name = "sk__mozhi_viewas",
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip
  end,
  view_as =function (self, cards, player)
    if #cards ~= 1 then return end
    local card = Fk:cloneCard(player:getMark("sk__mozhi-turn"))
    card:addSubcard(cards[1])
    card.skillName = "sk__mozhi"
    return card
  end,
}
Fk:addSkill(sk__mozhi_viewas)
sp_caiwenji:addSkill(sk__chenqing)
sp_caiwenji:addSkill(sk__mozhi)
Fk:loadTranslationTable{
  ["sk_sp__caiwenji"] = "蔡文姬",
  ["#sk_sp__caiwenji"] = "蓝田踪容",

  ["sk__chenqing"] = "陈情",
  [":sk__chenqing"] = "每回合限一次，当一名角色进入濒死状态时，你可以令另一名角色摸四张牌，然后弃置X张牌（X为此技能发动的次数），"..
  "若其以此法弃置的牌花色各不相同，则其视为对濒死状态的角色使用一张【桃】。",
  ["sk__mozhi"] = "默识",
  [":sk__mozhi"] = "一名角色回合结束时，若其本回合使用的最后一张牌是基本牌或普通锦囊牌，你可以将一张手牌当此牌使用。",
  ["#sk__chenqing-choose"] = "陈情：令一名角色摸四张牌然后弃%arg张牌，若花色各不相同视为对 %dest 使用【桃】",
  ["#sk__chenqing-discard"] = "陈情：请弃置%arg张牌，若花色各不相同视为对 %dest 使用【桃】",
  ["#sk__mozhi-invoke"] = "默识：你可以将一张手牌当【%arg】使用",
  ["sk__mozhi_viewas"] = "默识",

  ["$sk__chenqing1"] = "难陈生死别离之苦。",
  ["$sk__chenqing2"] = "罪难宽恕，情有可原。",
  ["$sk__mozhi1"] = "诗书千卷，默识于心。",
  ["$sk__mozhi2"] = "默书古籍，以报君恩。",
  ["~sk_sp__caiwenji"] = "",
}

local wanniangongzhu = General(extension, "sk__wanniangongzhu", "qun", 3, 3, General.Female)
local sk__zhenge = fk.CreateTriggerSkill{
  name = "sk__zhenge",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished, fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.CardUseFinished then
        return not (data.extra_data and data.extra_data.sk__zhenge)
      elseif event == fk.TargetSpecified then
        return data.extra_data and data.extra_data.sk__zhenge and #AimGroup:getAllTargets(data.tos) == 1 and
          not player.room:getPlayerById(data.to).dead and data.card.color ~= Card.NoColor
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardUseFinished then
      local card = room:getNCards(1, "bottom")
      room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, false, player.id, "@@sk__zhenge-inhand")
    else
      local to = room:getPlayerById(data.to)
      local color = data.card:getColorString()
      if room:askForSkillInvoke(player, self.name, nil, "#sk__zhenge_"..color.."-invoke::"..to.id) then
        local info
        if color == "black" then
          info = table.random({1, 2, 4, 26, 27, 28, 31, 34, 35, 40, 41, 42})
        elseif color == "red" then
          info = table.random({3, 5, 6, 7, 8, 9, 21, 22, 23, 24, 25, 30, 32, 33, 37, 38, 39})
        end
        SkUtil.DoTiangongEffect(player, to, info, self.name)
      end
    end
  end,

  refresh_events = {fk.PreCardUse},
  can_refresh = function(self, event, target, player, data)
    return player == target and player:hasSkill(self) and data.card:getMark("@@sk__zhenge-inhand") > 0
  end,
  on_refresh = function(self, event, target, player, data)
    data.extra_data = data.extra_data or {}
    data.extra_data.sk__zhenge = true
  end,
}
local sk__zhenge_maxcards = fk.CreateMaxCardsSkill{
  name = "#sk__zhenge_maxcards",
  exclude_from = function(self, player, card)
    return card and card:getMark("@@sk__zhenge-inhand") > 0
  end,
}
local sk__zhenge_targetmod = fk.CreateTargetModSkill{
  name = "#sk__zhenge_targetmod",
  bypass_times = function(self, player, skill, scope, card)
    return card and card:getMark("@@sk__zhenge-inhand") > 0
  end,
}
local sk__xinghan_ban_list = {
  "zuoci", "ol_ex__zuoci", "js__xushao", "shichangshi", "sk__zuoci"
}
local sk__xinghan = fk.CreateTriggerSkill{
  name = "sk__xinghan",
  anim_type = "special",
  events = {fk.GameStart, fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and (event == fk.GameStart or (event == fk.TurnStart and target == player))
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local all_kingdoms, generals = {}, {}
    for _, general in ipairs(room.general_pile) do
      if not table.contains(sk__xinghan_ban_list, general) and
        not table.contains(player:getTableMark("sk__xinghan_selected"), general) and
        not Fk.generals[general].subkingdom then
        local kingdom = Fk.generals[general].kingdom
        table.insertIfNeed(all_kingdoms, kingdom)
        generals[kingdom] = generals[kingdom] or {}
        table.insert(generals[kingdom], general)
      end
    end
    local kingdoms = table.filter(all_kingdoms, function (kingdom)
      return not table.contains(player:getTableMark("sk__xinghan_invalid_kingdoms"), kingdom)
    end)
    if #player:getTableMark("@&sk__xinghan") == 3 then
      kingdoms = table.filter(kingdoms, function (kingdom)
        return table.find(player:getTableMark("@&sk__xinghan"), function (general)
          return Fk.generals[general].kingdom == kingdom
        end)
      end)
    end
    if #kingdoms == 0 then return end
    local choices, all_choices = {}, {}
    for _, kingdom in ipairs({"wei", "shu", "wu", "qun", "jin", "god"}) do
      if table.contains(all_kingdoms, kingdom) then
        table.insert(all_choices, kingdom)
      end
      if table.contains(kingdoms, kingdom) then
        table.insert(choices, kingdom)
      end
    end
    for _, kingdom in ipairs(all_kingdoms) do
      table.insertIfNeed(all_choices, kingdom)
    end
    for _, kingdom in ipairs(kingdoms) do
      table.insertIfNeed(choices, kingdom)
    end
    local choice = room:askForChoice(player, choices, self.name, "#sk__xinghan-kingdom", false, all_choices)
    local general_choices = table.random(generals[choice], 3)
    local general_skills = {}
    for _, general in ipairs(general_choices) do
      table.insert(general_skills, Fk.generals[general]:getSkillNameList())
    end
    local result = room:askForCustomDialog(
      player, self.name,
      "packages/utility/qml/ChooseSkillFromGeneralBox.qml",
      { general_choices, general_skills, "#sk__xinghan-general" }
    )
    if result == "" then
      result = {general_choices[1]}
    else
      result = json.decode(result)
    end
    local general, _ = table.unpack(result)
    room:addTableMark(player, "sk__xinghan_selected", general)
    local mark = player:getTableMark("@&sk__xinghan")
    if #mark > 0 then
      for i = 1, #mark, 1 do
        local g = mark[i]
        if Fk.generals[general].kingdom == Fk.generals[g].kingdom then
          if room:askForSkillInvoke(player, self.name, nil, "#sk__xinghan-change:::"..g..":"..general) then
            table.removeOne(room.general_pile, general)
            room:returnToGeneralPile(Fk.generals[g])
            mark[i] = general
            room:setPlayerMark(player, "@&sk__xinghan", mark)
          end
          return
        end
      end
    end
    table.removeOne(room.general_pile, general)
    room:addTableMark(player, "@&sk__xinghan", general)
    room:addTableMark(player, "sk__xinghan_hp", Fk.generals[general].hp)
  end,
}
local sk__xinghan_delay = fk.CreateTriggerSkill{
  name = "#sk__xinghan_delay",
  anim_type = "special",
  events = {fk.AfterTurnEnd, fk.AskForPeachesDone},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:getMark("@&sk__xinghan") ~= 0 then
      if event == fk.AfterTurnEnd then
        return not player:insideExtraTurn()
      elseif event == fk.AskForPeachesDone then
        return player:getMark("sk__xinghan_status") > 0
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.AfterTurnEnd then
      local isDeputy = player.deputyGeneral == "sk__wanniangongzhu"
      if isDeputy then
        room:setPlayerMark(player, "sk__xinghan_orig", {player.deputyGeneral, 2, player.hp})
      else
        room:setPlayerMark(player, "sk__xinghan_orig", {player.general, 1, player.hp})
      end
      for i = 1, 3, 1 do
        if player.dead then return end
        if #player:getTableMark("@&sk__xinghan") < i then
          break
        end

        for _, p in ipairs(room.players) do
          p:setCardUseHistory("", 0, Player.HistoryTurn)
          p:setSkillUseHistory("", 0, Player.HistoryTurn)
          for name, _ in pairs(p.mark) do
            if name:find("-turn", 1, true) then
              room:setPlayerMark(p, name, 0)
            end
          end
        end
        for cid, cmark in pairs(room.card_marks) do
          for name, _ in pairs(cmark) do
            if name:find("-turn", 1, true) then
              room:setCardMark(Fk:getCardById(cid), name, 0)
            end
          end
        end

        for _, p in ipairs(room.players) do
          p:filterHandcards()
          room:broadcastProperty(p, "MaxCards")
        end

        if player:getMark("sk__xinghan_hp")[i] > 0 then
          room:setPlayerMark(player, "sk__xinghan_status", i)
          local general = player:getMark("@&sk__xinghan")[i]
          room:changeHero(player, general, false, isDeputy, true, true, true)
          if player.dead then return end
          room:setPlayerProperty(player, "hp", math.min(player:getMark("sk__xinghan_hp")[i], player.maxHp))
          if player.dead then return end
          player:gainAnExtraTurn(false, self.name)
          if player.dead then return end
          local mark = player:getMark("sk__xinghan_hp")
          mark[i] = player.hp
          room:setPlayerMark(player, "sk__xinghan_hp", mark)
        end
      end
      if not player.dead then
        local choices = {player:getMark("sk__xinghan_orig")[1]}
        for i = 1, 3, 1 do
          if #player:getTableMark("@&sk__xinghan") < i then
            break
          end
          if player:getMark("sk__xinghan_hp")[i] > 0 then
            table.insert(choices, player:getMark("@&sk__xinghan")[i])
          end
        end
        if #choices == 1 then return end
        local skills = {}
        for _, general in ipairs(choices) do
          table.insert(skills, Fk.generals[general]:getSkillNameList())
        end
        local result = room:askForCustomDialog(
          player, self.name,
          "packages/utility/qml/ChooseSkillFromGeneralBox.qml",
          { choices, skills, "#sk__xinghan-changeHero" }
        )
        if result == "" then
          result = {choices[1]}
        else
          result = json.decode(result)
        end
        local general, _ = table.unpack(result)
        if isDeputy and general ~= player.deputyGeneral or general ~= player.general then
          local mark = player:getMark("sk__xinghan_hp")
          mark[player:getMark("sk__xinghan_status")] = player.hp
          room:setPlayerMark(player, "sk__xinghan_hp", mark)
          if general == player:getMark("sk__xinghan_orig")[1] then
            room:setPlayerMark(player, "sk__xinghan_status", 0)
            room:changeHero(player, general, false, isDeputy, true, true, true)
            if player.dead then return end
            room:setPlayerProperty(player, "hp", math.min(player:getMark("sk__xinghan_orig")[3], player.maxHp))
            room:setPlayerMark(player, "sk__xinghan_orig", 0)
          else
            local status = table.indexOf(player:getMark("@&sk__xinghan"), general)
            room:setPlayerMark(player, "sk__xinghan_status", status)
            room:changeHero(player, general, false, isDeputy, true, true, true)
            if player.dead then return end
            room:setPlayerProperty(player, "hp", math.min(player:getMark("sk__xinghan_hp")[status], player.maxHp))
          end
        end
      end
    elseif event == fk.AskForPeachesDone then
      room:addTableMark(player, "sk__xinghan_invalid_kingdoms",
        Fk.generals[player:getMark("@&sk__xinghan")[player:getMark("sk__xinghan_status")]].kingdom)
      local mark = player:getMark("sk__xinghan_hp")
      mark[player:getMark("sk__xinghan_status")] = player.hp
      room:setPlayerMark(player, "sk__xinghan_hp", mark)
      if player:getMark("sk__xinghan_status") < #player:getMark("@&sk__xinghan") then
        for i = player:getMark("sk__xinghan_status"), #player:getMark("@&sk__xinghan"), 1 do
          if player:getMark("sk__xinghan_hp")[i] > 0 then
            room:setPlayerMark(player, "sk__xinghan_status", i)
            local general = player:getMark("@&sk__xinghan")[i]
            local isDeputy = player:getMark("sk__xinghan_orig")[2] == 2
            room:changeHero(player, general, false, isDeputy, true, true, true)
            if player.dead then return end
            room:setPlayerProperty(player, "hp", math.min(player:getMark("sk__xinghan_hp")[i], player.maxHp))
            return
          end
        end
      end
      room:setPlayerMark(player, "sk__xinghan_status", 0)
      local isDeputy = player:getMark("sk__xinghan_orig")[2] == 2
      room:changeHero(player, player:getMark("sk__xinghan_orig")[1], false, isDeputy, true, true, true)
      if player.dead then return end
      room:setPlayerProperty(player, "hp", math.min(player:getMark("sk__xinghan_orig")[3], player.maxHp))
      room:setPlayerMark(player, "sk__xinghan_orig", 0)
    end
  end,

  refresh_events = {fk.BeforeTurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("@&sk__xinghan") ~= 0 and not player:insideExtraTurn() and
      player:getMark("sk__xinghan_status") > 0 and player:getMark("sk__xinghan_orig") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getMark("sk__xinghan_hp")
    mark[player:getMark("sk__xinghan_status")] = player.hp
    room:setPlayerMark(player, "sk__xinghan_hp", mark)
    room:setPlayerMark(player, "sk__xinghan_status", 0)
    local isDeputy = player:getMark("sk__xinghan_orig")[2] == 2
    room:changeHero(player, player:getMark("sk__xinghan_orig")[1], false, isDeputy, true, true, true)
    if player.dead then return end
    room:setPlayerProperty(player, "hp", math.min(player:getMark("sk__xinghan_orig")[3], player.maxHp))
    room:setPlayerMark(player, "sk__xinghan_orig", 0)
  end,
}
sk__zhenge:addRelatedSkill(sk__zhenge_maxcards)
sk__zhenge:addRelatedSkill(sk__zhenge_targetmod)
sk__xinghan:addRelatedSkill(sk__xinghan_delay)
wanniangongzhu:addSkill(sk__zhenge)
wanniangongzhu:addSkill(sk__xinghan)
Fk:loadTranslationTable{
  ["sk__wanniangongzhu"] = "万年公主",
  ["#sk__wanniangongzhu"] = "汉之遗珠",

  ["sk__zhenge"] = "枕戈",
  [":sk__zhenge"] = "锁定技，当你使用非“枕戈”牌后，你获得牌堆底牌并标记为“枕戈”牌，你的“枕戈”牌不计入手牌上限，你使用“枕戈”牌无次数限制。"..
  "当你使用黑色/红色“枕戈”牌指定唯一目标后，你可以令其受到随机负面/正面效果。<br>"..
  "<font color='grey'><small>随机负面/正面效果：极略SP神黄月英天工技能的部分效果。</small></font>",
  ["sk__xinghan"] = "兴汉",
  [":sk__xinghan"] = "游戏开始时或回合结束时，你可以选择一个势力，从武将牌堆中三名此势力的未以此法选择过的武将中招募一名武将。"..
  "你至多拥有三名势力各不相同的招募武将，若选择招募已有势力的武将，你选择是否替换之。<br>"..
  "你的额定回合结束后，你依次变身为招募武将并依次执行一个额外回合。然后你选择变身为原武将或招募武将。你的额定回合开始前，变身为原武将。<br>"..
  "原武将和每名招募武将的体力值分别独立计算。<br>"..
  "当你阵亡前，若为招募武将，则改为不可再从该势力中招募，然后变身为下一名武将。<br>"..
  "<font color='red'>注：此技能显然有极大的结算问题，请不要尝试与变更武将、插入回合、复活类技能进行搭配</font>",
  ["@@sk__zhenge-inhand"] = "枕戈",
  ["#sk__zhenge_black-invoke"] = "枕戈：是否令 %dest 执行随机负面效果？",
  ["#sk__zhenge_red-invoke"] = "枕戈：是否令 %dest 执行随机正面效果？",
  ["@&sk__xinghan"] = "兴汉",
  ["#sk__xinghan-kingdom"] = "兴汉：选择招募武将的势力",
  ["#sk__xinghan-general"] = "兴汉：选择要招募的武将",
  ["#sk__xinghan-change"] = "兴汉：是否要将 %arg 替换为 %arg2？",
  ["#sk__xinghan_delay"] = "兴汉",
  ["#sk__xinghan-changeHero"] = "兴汉：回合结束，请选择你要变身成为的武将",
}

return extension
